﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;

namespace QuickChat
{
    public partial class ChatForm : Form
    {
        private User me;
        private List<User> users;
        private List<ChatRecords> chatrecords;
        private Connect connection;
        private string currentUser;
        delegate void RefreshUsersCallback();
        delegate void RefreshMessagesCallback(ChatRecords cr);

        #region 构造函数
        public ChatForm(string user)
        {
            InitializeComponent();

            users = new List<User>();
            chatrecords = new List<ChatRecords>();

            me = new User();
            this.me.username = user;
            IPAddress[] ips = Dns.GetHostByName(Dns.GetHostName()).AddressList;
            this.me.IP = ips[0].ToString();

            connection = new Connect(me,this);
            connection.login();

            connection.somebodyLogin += connection_somebodyLogin;
            connection.somebodyLogout += connection_somebodyLogout;
            connection.somebodyOnline += connection_somebodyOnline;
            connection.somebodyTalk += connection_somebodyTalk;
        }
        #endregion

        #region 事件
        void connection_somebodyTalk(ChatRecord talkRecord)
        {
            MessageBox.Show(talkRecord.username + "给您发送了一条信息！");

            foreach (ChatRecords c in chatrecords)
            {
                if (c.username.Equals(me.username) && c.friendname.Equals(talkRecord.username))
                {
                    c.records.Add(talkRecord);
                    if(talkRecord.username.Equals(currentUser))
                        RefreshMessages(c);
                    return;
                }
            }

            ChatRecords cr = new ChatRecords();
            cr.username = me.username;
            cr.friendname = talkRecord.username;
            cr.records.Add(talkRecord);
            chatrecords.Add(cr); 
        }

        void connection_somebodyOnline(User onlineUser)
        {
            if (!users.Contains(onlineUser) && !onlineUser.username.Equals(me.username))
            {
                users.Add(onlineUser);
                RefreshUsers();
            }
        }

        void connection_somebodyLogout(User logoutUser)
        {
            if (!logoutUser.username.Equals(me.username))
            {
                MessageBox.Show(logoutUser.username + "下线了！");

                for (int i = 0; i < users.Count;++i )
                {
                    if (users[i].username.Equals(logoutUser.username))
                        users.Remove(users[i]);
                }
                RefreshUsers();
            }
        }

        void connection_somebodyLogin(User loginUser)
        {
            if (!loginUser.username.Equals(me.username))
            {
                MessageBox.Show(loginUser.username + "上线了！");

                users.Add(loginUser);
                RefreshUsers();
            }
        }
        #endregion

        #region 界面控制
        private void RefreshUsers()
        {
            if (this.lbUsers.InvokeRequired)
            {
                RefreshUsersCallback d = new RefreshUsersCallback(RefreshUsers);
                this.Invoke(d, new object[] { });
            }
            else
            {
                lbUsers.SelectedItem = null;

                if (lbUsers.Items.Count > 0)
                {
                    lbUsers.DataSource = null;
                    lbUsers.Items.Clear();
                }

                lbUsers.DataSource = users;
                lbUsers.DisplayMember = "username";
                lbUsers.Refresh();
            }
        }

        private void RefreshMessages(ChatRecords messages)
        {
            if (this.InvokeRequired)
            {
                RefreshMessagesCallback d = new RefreshMessagesCallback(RefreshMessages);
                this.Invoke(d, new object[] {messages});
            }
            else
            {
                rtbMessages.Clear();

                foreach (ChatRecord c in messages.records)
                {
                    if (c.username.Equals(me.username))
                    {
                        rtbMessages.SelectionColor = Color.Green;
                        rtbMessages.AppendText(c.messsage.time + "  " + c.username + "  "+ c.messsage.content + '\n');
                    }
                    else
                    {
                        rtbMessages.SelectionColor = Color.Black;
                        rtbMessages.AppendText(c.messsage.time + "  " + c.username + "  " + c.messsage.content + '\n');
                    }
                }
                rtbMessages.Select(rtbMessages.Text.Length, 0);
                rtbMessages.ScrollToCaret();
            }
        }
        #endregion

        #region 聊天控制
        private void lbUsers_DoubleClick(object sender, EventArgs e)
        {
            if (lbUsers.SelectedItem != null)
            {
                User temp = (User)lbUsers.SelectedItem;
                currentUser = temp.username;
                lblChatTo.Text = temp.username;

                foreach (ChatRecords c in chatrecords)
                {
                    if (c.username.Equals(me.username) && c.friendname.Equals(temp.username))
                    {
                        RefreshMessages(c);
                        return;
                    }
                }

                ChatRecords cr = new ChatRecords();
                cr.username = me.username;
                cr.friendname = temp.username;
                chatrecords.Add(cr);
                RefreshMessages(cr);
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (rtbInput.Text.Length != 0)
            {
                User friend = (User)lbUsers.SelectedItem;
                ChatRecord recordtosend = new ChatRecord();

                recordtosend.username = me.username;
                recordtosend.messsage.time = DateTime.Now.ToString();
                recordtosend.messsage.content = rtbInput.Text;

                AddRecord(recordtosend,friend.username);
                connection.talk(friend.IP, recordtosend);
                rtbInput.Clear();
            }
            else
                MessageBox.Show("请不要发送空消息");
        }

        private void AddRecord(ChatRecord record,string friendname)
        {
            foreach (ChatRecords c in chatrecords)
            {
                if (c.username.Equals(me.username) && c.friendname.Equals(friendname))
                {
                    c.records.Add(record);
                    RefreshMessages(c);
                    return;
                }
            }

            ChatRecords cr = new ChatRecords();
            cr.username = me.username;
            cr.friendname = friendname;
            cr.records.Add(record);
            chatrecords.Add(cr);
            RefreshMessages(cr);       
        }
        #endregion

        #region 聊天记录
        private void btnChatRecord_Click(object sender, EventArgs e)
        {
            User selected = (User)lbUsers.SelectedItem;

            ChatRecordFrom crform = new ChatRecordFrom(me.username, selected.username);

            crform.StartPosition = FormStartPosition.CenterScreen;
            crform.ShowDialog();
        }
        #endregion

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string filepath = ofd.FileName;
                connection.sendFile(filepath, (lbUsers.SelectedItem as User).IP);
            }
            lblFile.Text = "正在传输文件...";
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            connection.logout();
            foreach (ChatRecords cr in chatrecords)
            {
                FileManagement.SaveChatRecords(cr);
            }
            connection.dispose();
            this.Close();
        }

        private void btnQuitChat_Click(object sender, EventArgs e)
        {
            lbUsers.SelectedItem = null;
            rtbMessages.Clear();
            rtbInput.Clear();
        }
    }
}
